#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include <iostream>
#include <cmath>

using namespace cv;
using namespace std;

Mat rectang(Mat);

Mat src, dst;
Mat hsv, inrange, gray;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
RotatedRect box[10];
Rect rect_suit[10];

//Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));

int main()
{

    VideoCapture capture;
    int ret = capture.open("/home/zdr/video.avi");
    int rate = capture.get(CV_CAP_PROP_FPS);
    VideoWriter writer("/home/zdr/video/writen_video.avi", CV_FOURCC('M', 'J', 'P', 'G'), rate, Size(640, 480));

    while(1)
    {
      Mat frame;
      capture>>frame;
      if(frame.empty()) break;
      frame = rectang(frame);
      //imshow("image", frame);
      writer<<frame;
      //if(waitKey(25)==27)
        //imwrite("/home/zdr/dir/src/testimage.jpg", frame);
        //break;
    }

/*
    Mat inputImg = imread("/home/zdr/images/63856435.jpg");
    rectang(inputImg);
*/
    //waitKey(0);
    return 0;
}

Mat rectang(Mat image)
{
  int x, y, w, h;
  int k=0;
  //cout<<image.rows<<"	"<<image.cols<<endl;
  cvtColor(image, hsv, COLOR_BGR2HSV);
  inRange(hsv, Scalar(0, 43, 46), Scalar(25, 255, 255), inrange);//90 124     0 25
  //erode(inrange, inrange, element);
  morphologyEx(inrange, inrange, MORPH_OPEN, (5, 15));
  //namedWindow("inrange", WINDOW_AUTOSIZE);
  //imshow("inrange", inrange);
  cvtColor(image, gray, COLOR_BGR2GRAY);
  threshold(gray, gray, 70, 255, 0);
  morphologyEx(gray, gray, MORPH_OPEN, (5, 15));
  //namedWindow("gray", WINDOW_AUTOSIZE);
  //imshow("gray", gray);
  bitwise_and(gray, inrange, dst);
  //namedWindow("dst", WINDOW_AUTOSIZE);
  //imshow("dst", dst);
  //createTrackbar("threshold", "thre", &g_thre, 0, )
  //thre(Range(0, 90), Range::all()) = 0;
  transpose(dst, dst);
  transpose(image, image);
  findContours(dst, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  for(int i=0; i<contours.size(); i++)
  {
    Rect rect = boundingRect(contours[i]);
    if(rect.height*1.5<rect.width && rect.width>5 && rect.height*20>rect.width) //select the suitable contour
    {
      if(contourArea(contours[i])>10)//contours area > 10
	{
	  rect_suit[k] = boundingRect(contours[i]);
	  //cout<<contours[i][0]<<endl;
          //drawContours(image, contours, i, Scalar(0, 0, 255));
	  box[k] = minAreaRect(contours[i]);//get the minarea rectangle
	  //cout<<"box k angle: "<<box[k].angle<<endl;
	  Point2f vertex[4];
	  box[k].points(vertex);
	  for(int j=0; j<4; j++)
	  {
	    line(image, vertex[j], vertex[(j+1)%4], Scalar(100, 200, 211), 2);
	  }
	  if(k>0)
	  //cout<<"delta angle: "<<abs(box[k].angle-box[k-1].angle)<<endl;
	  if(k>0)
	  {
	    if(abs(box[k].angle-box[k-1].angle)<10 || abs(box[k].angle-box[k-1].angle)>80)
		{
		   //cout<<"the k 's width: "<<rect_suit[k].width<<"	the k-1 's width: "<<rect_suit[k-1].width<<endl;
		   //cout<<"k's x: "<<rect_suit[k].x<<"	k-1 's x: "<<rect_suit[k-1].x<<endl;
		   //cout<<"delta witdh: "<<abs(rect_suit[k].x-rect_suit[k-1].x)*5<<endl;
		   if(abs(rect_suit[k].x-rect_suit[k-1].x)*2.5<rect_suit[k].width && (rect_suit[k-1].y-rect_suit[k].y)<3*rect_suit[k].width && abs(rect_suit[k-1].width-rect_suit[k].width)<20)
		   {
		    line(image, Point(rect_suit[k-1].x, rect_suit[k-1].y), Point(rect_suit[k].x+rect_suit[k-1].width, rect_suit[k].y), Scalar(0, 200, 200), 2);
		    line(image, Point(rect_suit[k-1].x+rect_suit[k-1].width, rect_suit[k-1].y), Point(rect_suit[k].x, rect_suit[k].y), Scalar(0, 200, 200), 2);
		    circle(image, Point(rect_suit[k-1].x+rect_suit[k-1].width/2, (rect_suit[k-1].y+rect_suit[k].y)/2), 2, Scalar(255, 255, 0), 3);
		    //cout<<"center point: ("<<rect_suit[k-1].x+rect_suit[k-1].width/2<<", "<<(rect_suit[k-1].y+rect_suit[k].y)/2<<")"<<endl;
		   }
		}
	  }

	  k++;

	}
    }
  }
  //cout<<"=================="<<endl;
  transpose(image, image);
  //imshow("image", image);
  //writer << image;
  return image;
}
